home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / ABUSESRC.ZIP / AbuseSrc / imlib / readwav.c < prev    next >
C/C++ Source or Header  |  1996-04-11  |  4KB  |  169 lines

  1. #include "readwav.hpp"
  2. #include "specs.hpp"
  3. #include "macs.hpp"
  4. #include "dprint.hpp"
  5.  
  6. struct wav_chunk
  7. {
  8.   char id[4];
  9.   unsigned long size;
  10.   char type[4];
  11. } ;
  12.  
  13. struct wav_tag
  14. {
  15.   char id[4];
  16.   unsigned long size;
  17. } ;
  18.  
  19.  
  20. struct wav_format
  21. {
  22.   unsigned short fmt_tag,channels;
  23.   unsigned long samplesps,avg_bytesps;
  24.   unsigned short align;
  25. } ;
  26.  
  27.  
  28. struct pcm_wave
  29. {
  30.   wav_format wf;
  31.   unsigned short bitsps;
  32. } ;
  33.  
  34.  
  35.  
  36.  
  37. void read_chunk(wav_chunk &chunk, bFILE *fp)
  38. {
  39.   fp->read(&chunk.id,4);
  40.   chunk.size=fp->read_long();
  41.   fp->read(&chunk.type,4);  
  42. }
  43.  
  44. void read_tag(wav_tag &tag, bFILE *fp)
  45. {
  46.   fp->read(&tag.id,4);
  47.   tag.size=fp->read_long();
  48. }
  49.  
  50. void read_wav_format(wav_format &fmt, bFILE *fp)
  51. {
  52.   fmt.fmt_tag=fp->read_short();
  53.   fmt.channels=fp->read_short(); 
  54.   fmt.samplesps=fp->read_long();
  55.   fmt.avg_bytesps=fp->read_long();  
  56.   fmt.align=fp->read_short();  
  57. }
  58.  
  59.  
  60. void read_pcm(pcm_wave &pcm, bFILE *fp)
  61. {
  62.   read_wav_format(pcm.wf,fp);
  63.   pcm.bitsps=fp->read_short();  
  64. }
  65.  
  66.  
  67.  
  68. void write_wav(char *filename, long sample_rate, long data_size, unsigned char *data)
  69. {
  70.   wav_chunk chunk;
  71.   wav_tag tag;
  72.   pcm_wave pcm;  
  73.  
  74.   
  75.   bFILE *fp=open_file(filename,"wb");
  76.   if (fp->open_failure())
  77.   {
  78.     printf("Unable to open %s for writing\n");
  79.     delete fp;
  80.     exit(1);
  81.   }
  82.  
  83.   /***************  Write the chunk ***************************/
  84.   fp->write("RIFF",4);  
  85.   fp->write_long(data_size+36);
  86.   fp->write("WAVE",4);
  87.  
  88.  
  89.   /************** Write the tag *******************************/
  90.   fp->write("fmt ",4);
  91.   fp->write_long(16);
  92.   
  93.   
  94.   /************** Write PCM ***********************************/
  95.   fp->write_short(1);          // format_tag
  96.   fp->write_short(1);          // mono recording
  97.   fp->write_long(sample_rate);
  98.   fp->write_long(sample_rate);   // average bytes per sec
  99.   fp->write_short(1);    // allignment? Don't know what this does?
  100.   fp->write_short(8);    // 8 bits per sample
  101.   
  102.   /************* Write data tag ******************************/
  103.   fp->write("data",4);
  104.   fp->write_long(data_size);
  105.  
  106.   /************ Now write sample data ************************/
  107.   fp->write(data,data_size);
  108.  
  109.   delete fp;
  110. }
  111.  
  112.  
  113.  
  114. unsigned char *read_wav(char *filename, long &sample_rate, long &data_size)
  115. {
  116.   unsigned char *data;
  117.   wav_chunk chunk;
  118.   wav_tag tag;
  119.   pcm_wave pcm;  
  120.  
  121.   bFILE *fp=open_file(filename,"rb");
  122.   if (fp->open_failure())
  123.   { delete fp; return NULL; }
  124.   read_chunk(chunk,fp);      
  125.   if (memcmp(chunk.type,"WAVE",4)!=0)
  126.   {
  127.     printf("Bad WAV file (chunk) %s\n",filename);
  128.     delete fp;
  129.     return NULL;    
  130.   }
  131.   
  132.   read_tag(tag,fp);
  133.   if (memcmp(tag.id,"fmt ",4)!=0)
  134.   {
  135.     printf( "fmt tag missing, bad file (%s)\n",filename);
  136.     delete fp;
  137.     return NULL;
  138.   }
  139.  
  140.  
  141.   read_pcm(pcm,fp);
  142.  
  143.   fp->seek(tag.size-16,SEEK_CUR);  // seek to offset of sample
  144.  
  145.   read_tag(tag,fp);
  146.  
  147.   if (memcmp(tag.id,"data",4)!=0)
  148.   {
  149.     printf("Bad Wav file (tag), %s\n",filename);
  150.     delete fp;
  151.     return NULL;
  152.   }
  153.   
  154.   data_size=tag.size;  
  155.   data=(unsigned char *)jmalloc(tag.size,"WAV data");
  156.   ERROR(data,"Malloc error");
  157.  
  158.   sample_rate=pcm.wf.samplesps;     
  159.   ERROR(fp->read(data,tag.size)==tag.size,"Premature end of file");
  160.   ERROR(pcm.bitsps==8,"Only 8-bit samples supported");
  161.   ERROR(pcm.wf.channels==1,"Only mono samples supported");  
  162.   ERROR(pcm.wf.align==1,"Bad block allignment");   
  163.   delete fp;
  164.   return data;
  165. }
  166.  
  167.  
  168.  
  169.